import { defineStore } from 'pinia'
import type { RouteRecordRaw } from 'vue-router'
import { CacheManager } from '@/cache'
import { MenuUtils } from '@/utils/MenuUtils'
import router from '@/router'

/**
 * 菜单路由相关状态存储
 */
export const useMenuStore = defineStore('menu', () => {
  //是否加载动态路由完毕，每次刷新浏览器此属性的值都会重置为false，第二次进入全局路由守卫时需要一个标识用于退出
  const loading = ref(false)
  //静态菜单列表，不需要持久化，因为是前端直接获取
  const staticMenus = ref<Array<MenuRecordRaw>>([])
  //静态路由
  const staticRouterSet = ref(new Set<RouteRecordRaw>())
  //动态菜单列表，树形结构
  const dynamicMenus = ref<Array<MenuRecordRaw>>(CacheManager.getDynamicMenus())
  //所有菜单配置，key为id，value为路由配置
  const menuMap = ref(new Map<string, MenuRecordRaw>())
  //需要缓存的组件名
  const keepAliveNameSet = ref(new Set<string>())
  //标签列表
  const tagIdList = ref(CacheManager.getTagIdList())
  //标签页历史记录
  const tagHistory = ref(CacheManager.getTagHistory())
  /**
   * 包含静态路由，以及所有用户均可使用的公共路由和菜单
   * 部分菜单的ID是前端生成的，为了保证刷新浏览器之后重新拿到的菜单ID不变，所以需要保存
   * @param staticMenuList 保存路由或菜单
   */
  const saveStaticMenus = (staticMenuList: Array<MenuRecordRaw>) => {
    staticMenus.value = MenuUtils.processList(
      staticMenuList,
      menuMap.value,
      staticRouterSet.value,
      keepAliveNameSet.value
    )
    processTagIdList()
  }

  /**
   * 处理标签页列表
   */
  const processTagIdList = () => {
    const ids = [...menuMap.value.values()]
      .filter((item) => item.menuType === 'router')
      .filter((item) => item.isAffix)
      .map((item) => item.id)
      .filter((id) => id !== undefined)
    tagIdList.value = new Set<string>([...ids, ...tagIdList.value])
    CacheManager.setTagIdList(tagIdList.value)
  }

  /**
   * 初始动态路由或菜单
   */
  const initDynamicMenus = async () => {
    const routerSet = new Set<RouteRecordRaw>()
    if (dynamicMenus.value.length === 0) {
      //请求接口获取路由
      // const response = await service.get<{ menus: Array<MenuRecordRaw> }>('/currentMenus')
      //todo
      const response: { menus: MenuRecordRaw[] } = {
        menus: [
          {
            title: '首页',
            menuType: 'router',
            path: '/',
            component: '/system/Home.vue',
            keepAlive: true,
            componentName: 'Home',
            isAffix: true
          },
          {
            title: '文件上传',
            menuType: 'router',
            path: '/upload',
            component: '/system/Upload.vue',
            keepAlive: false,
            componentName: 'Upload',
            isAffix: false
          },
          {
            title: '编辑器',
            menuType: 'router',
            path: '/editor',
            component: '/system/Editor.vue',
            keepAlive: false,
            componentName: 'Editor',
            isAffix: false
          },
          {
            title: '菜单1',
            menuType: 'dir',
            icon: 'fold',
            children: [
              {
                title: '菜单1-1',
                menuType: 'router',
                path: '/path1-1',
                component: '/system/System.vue',
                keepAlive: true,
                componentName: 'System',
                icon: 'location'
              },
              {
                title: '菜单1-2',
                menuType: 'router',
                path: '/path1-2',
                component: '/system/About.vue',
                keepAlive: true,
                componentName: 'About',
                icon: 'location',
                isAffix: false,
                children: [
                  {
                    title: '菜单1-2-1',
                    menuType: 'router',
                    path: '/path1-2-1',
                    component: '/system/System.vue',
                    keepAlive: true,
                    componentName: 'System'
                  },
                  {
                    title: '菜单1-2-2',
                    menuType: 'router',
                    path: '/path1-2-2',
                    component: '/system/About.vue',
                    keepAlive: true,
                    componentName: 'About'
                  }
                ]
              },
              {
                title: '菜单1-3',
                menuType: 'router',
                path: '/path1-3',
                component: '/system/System.vue',
                keepAlive: true,
                componentName: 'System',
                icon: 'location'
              },
              {
                title: '菜单1-4',
                menuType: 'router',
                path: '/path1-4',
                component: '/system/System.vue',
                keepAlive: true,
                componentName: 'System',
                icon: 'location'
              },
              {
                title: '菜单1-5',
                menuType: 'router',
                path: '/path1-5',
                component: '/system/System.vue',
                keepAlive: true,
                componentName: 'System',
                icon: 'location'
              },
              {
                title: '菜单1-6',
                menuType: 'router',
                path: '/path1-6',
                component: '/system/System.vue',
                keepAlive: true,
                componentName: 'System',
                icon: 'location'
              },
              {
                title: '菜单1-7',
                menuType: 'router',
                path: '/path1-7',
                component: '/system/System.vue',
                keepAlive: true,
                componentName: 'System',
                icon: 'location'
              },
              {
                title: '菜单1-8',
                menuType: 'router',
                path: '/path1-8',
                component: '/system/System.vue',
                keepAlive: true,
                componentName: 'System',
                icon: 'location'
              },
              {
                title: '菜单1-9',
                menuType: 'router',
                path: '/path1-9',
                component: '/system/System.vue',
                keepAlive: true,
                componentName: 'System',
                icon: 'location'
              },
              {
                title: '菜单1-10',
                menuType: 'router',
                path: '/path1-10',
                component: '/system/System.vue',
                keepAlive: true,
                componentName: 'System',
                icon: 'location'
              },
              {
                title: '菜单1-11',
                menuType: 'router',
                path: '/path1-11',
                component: '/system/System.vue',
                keepAlive: true,
                componentName: 'System',
                icon: 'location'
              },
              {
                title: '菜单1-12',
                menuType: 'router',
                path: '/path1-12',
                component: '/system/System.vue',
                keepAlive: true,
                componentName: 'System',
                icon: 'location'
              },
              {
                title: '菜单1-13',
                menuType: 'router',
                path: '/path1-13',
                component: '/system/System.vue',
                keepAlive: true,
                componentName: 'System',
                icon: 'location'
              }
            ]
          },
          {
            title: '跳转外部链接',
            menuType: 'link',
            oriURL: 'https://www.baidu.com',
            icon: 'location'
          },
          {
            title: 'Iframe',
            menuType: 'iframe',
            oriURL: 'http://localhost:8080',
            icon: 'location'
          }
        ]
      }
      dynamicMenus.value = MenuUtils.processList(
        response.menus,
        menuMap.value,
        routerSet,
        keepAliveNameSet.value
      )
      //存储处理之后的菜单列表，里面有ID相关信息，防止刷新浏览器ID改变
      CacheManager.setDynamicMenus(dynamicMenus.value)
    } else {
      dynamicMenus.value = MenuUtils.processList(
        dynamicMenus.value,
        menuMap.value,
        routerSet,
        keepAliveNameSet.value
      )
    }
    for (const routerItem of routerSet) {
      router.addRoute(routerItem)
    }
    processTagIdList()
    loading.value = true
  }
  //获取所有菜单，树形结构，并且按照顺序排列，包括禁用或隐藏的菜单
  const allTreeMenus = computed(() => MenuUtils.sort([...staticMenus.value, ...dynamicMenus.value]))
  //获取指定ID对应的菜单
  const getMenuById = (id: string): undefined | MenuRecordRaw => {
    //刷新浏览器时，调用此方法可能获取到undefined
    return menuMap.value.get(id)
  }

  //获取当前菜单
  const currentMenu = computed(() => {
    const route = router.currentRoute.value
    return getMenuById(route.meta.id as string) as ChildMenuRecordRaw
  })

  //保存历史
  const pushHistory = () => {
    const route = router.currentRoute.value
    if (!route.meta.isTopPage) {
      const currentId = route.meta.id as string
      tagIdList.value.add(currentId)
      tagHistory.value.push(currentId)
      CacheManager.setTagIdList(tagIdList.value)
      CacheManager.setTagHistory(tagHistory.value)
    }
  }
  //不传默认移除当前路由ID，返回即将跳转的新的路由
  const removeHistory = (routeId?: string) => {
    const route = router.currentRoute.value
    if (!routeId) {
      routeId = route.meta.id as string
    }
    tagIdList.value.delete(routeId)
    tagHistory.value = tagHistory.value.filter((item) => item !== routeId)
    CacheManager.setTagIdList(tagIdList.value)
    CacheManager.setTagHistory(tagHistory.value)
    return getLastRouteId()
  }
  //获取最后一次应该跳转的标签页
  const getLastRouteId = () => {
    if (!tagHistory.value.length) {
      const lastElement = [...tagIdList.value].pop() as string
      return getMenuById(lastElement) as MenuRecordRaw
    }
    return getMenuById(tagHistory.value[tagHistory.value.length - 1]) as MenuRecordRaw
  }
  //获取已经打开的标签页列表
  const getTagList = computed(() => {
    return Array.from(tagIdList.value)
      .map((id) => getMenuById(id) as MenuRecordRaw)
      .filter((item) => item !== undefined)
      .filter((item) => item.menuType !== 'dir')
  })
  //关闭标签页
  const closeTag = async (routeId?: string) => {
    const route = router.currentRoute.value
    if (!routeId) {
      routeId = route.meta.id as string
    }
    removeHistory(routeId)
    CacheManager.setTagHistory(tagHistory.value)
    processTagIdList()
    const lastMenu = getLastRouteId()
    //跳转最后一次的路由，不可能为空
    await router.push(lastMenu.path as string)
  }
  //关闭指定标签页左侧所有标签页
  const closeLeft = async (routeId?: string) => {
    for (const tagId of tagIdList.value) {
      if (routeId === tagId) {
        break
      }
      tagIdList.value.delete(tagId)
      tagHistory.value = tagHistory.value.filter((item: string) => item !== tagId)
    }
    CacheManager.setTagHistory(tagHistory.value)
    processTagIdList()
    const lastMenu = getLastRouteId()
    //跳转最后一次的路由，不可能为空
    await router.push(lastMenu.path as string)
  }
  //关闭右侧标签页，不包含当前标签页
  const closeRight = async (routeId?: string) => {
    const values = Array.from(tagIdList.value).reverse()
    for (const tagId of values) {
      if (routeId === tagId) {
        break
      }
      tagIdList.value.delete(tagId)
      tagHistory.value = tagHistory.value.filter((item: string) => item !== tagId)
    }
    CacheManager.setTagHistory(tagHistory.value)
    processTagIdList()
    const lastMenu = getLastRouteId()
    //跳转最后一次的路由，不可能为空
    await router.push(lastMenu.path as string)
  }
  //关闭所有标签页
  const closeAll = async () => {
    tagIdList.value = new Set<string>()
    tagHistory.value = []
    CacheManager.setTagHistory(tagHistory.value)
    processTagIdList()
    const lastMenu = getLastRouteId()
    //跳转最后一次的路由，不可能为空
    await router.push(lastMenu.path as string)
  }
  //指定标签页是否已经打开
  const hasTag = (routeId: string) => {
    return tagIdList.value.has(routeId)
  }
  const allowCloseTag = (routeId?: string) => {
    const route = router.currentRoute.value
    if (!routeId) {
      routeId = route.meta.id as string
    }
    return !(getMenuById(routeId) as RouteItem)?.isAffix
  }
  const allowCloseLeft = (routeId?: string) => {
    const route = router.currentRoute.value
    if (!routeId) {
      routeId = route.meta.id as string
    }
    const firstElement = [...tagIdList.value][0] as string | undefined
    if (routeId === firstElement) {
      //当前是第一个元素
      return false
    } else {
      // 将Set转换为数组
      const array = Array.from(tagIdList.value)
      // 查找目标元素的索引
      const index = array.indexOf(routeId)
      // 返回目标元素之前的元素
      const menu = (getMenuById(array[index - 1]) as RouteItem) || undefined
      return !menu?.isAffix
    }
  }
  //当前元素不是最后一个元素，并且存在最后一个元素支持关闭
  const allowCloseRight = (routeId?: string) => {
    const route = router.currentRoute.value
    if (!routeId) {
      routeId = route.meta.id as string
    }
    const lastElement = [...tagIdList.value].pop() as string
    if (routeId === lastElement) {
      //当前是最后一个元素
      return false
    }
    // 返回目标元素之后的元素
    const menu = (getMenuById(lastElement) as RouteItem) || undefined
    return !menu?.isAffix
  }
  const allowCloseAll = () => {
    const values = Array.from(tagIdList.value).reverse()
    for (const tagId of values) {
      const menu = getMenuById(tagId) as RouteItem | undefined
      if (!menu?.isAffix) {
        return true
      }
    }
    return false
  }
  return {
    loading,
    staticRouterSet,
    keepAliveNameSet,
    allTreeMenus,
    saveStaticMenus,
    initDynamicMenus,
    getMenuById,
    currentMenu,
    pushHistory,
    getLastRouteId,
    tagIdList,
    tagHistory,
    getTagList,
    closeTag,
    closeLeft,
    closeRight,
    closeAll,
    hasTag,
    allowCloseTag,
    allowCloseLeft,
    allowCloseRight,
    allowCloseAll
  }
})
